package ac.github.os.internal.core.config

import ac.github.os.api.event.InjectInternalScriptEvent
import ac.github.os.internal.core.script.BaseWrapper
import ac.github.os.internal.core.script.InternalScript
import ac.github.os.internal.session.Session
import ac.github.os.util.deSerialize
import ac.github.os.util.serialize

class StringConfig(
    val string: String = "",
) {

    lateinit var session: Session

    val map = mutableMapOf<String, String>()


    fun initial(session: Session) {
        this.session = session

        InjectInternalScriptEvent(session, session.list).call()
    }

    override fun toString(): String {
        return "StringConfig(map=$map)"
    }

    companion object {
        const val DEFAULT = "===default"
    }

    init {

        if (string.isNotEmpty() && string != "{}") {
            val serialize = string.substring(1, string.length - 1).serialize()
            serialize.split(";").forEach {
                val indexOf = it.indexOf("=")
                if (indexOf == -1) {
                    map[DEFAULT] = it.deSerialize()
                } else {
                    val key = it.substring(0, indexOf)
                    val value = it.substring(indexOf + 1)
                    map[key] = value.deSerialize()
                }
            }
        }

    }


}

inline fun <reified T> StringConfig.get(
    key: String,
    def: T? = null,
    single: Boolean = false,
): T? {

    val string: String? = if (single && map.size == 1) {
        map[key] ?: map[StringConfig.DEFAULT]
    } else {
        map[key]
    }
    if (string == null) return def

    val result = InternalScript.transform(string, session.trigger, session.list)
    val clazz = DataType.cover(T::class.java)
    val dataType = DataType.types[clazz]
    return dataType?.toValue(result, session) as T
}
